
/**
 * js与各平台交互的服务
 * Tips:
 * 1）使用mountAtWindow 挂载在窗口上，避免出现this指向问题。
 * 2）使用Static的方式获取实例。
 * 3）web调用plantform的交互为 callApp；plantform调用web的方法为appCallback。
 * 4）appCallback中的this是plantform端的，所以，用静态方法，获取window的HyBirdServer来使用。
 */
export default class HyBirdServer {
	private observers : Map<string, IReceiveObserver>
	// private builder;
	constructor() {
		this.observers = new Map();
	}

	/**
	 * 获取实例
	 */
	static getInstance() : HyBirdServer {
		return window.hyBirdServer;
	}

	/**
	 * 平台调用网页的方法,因为是平台调用的方法，所以此时的this是undefined。因此用静态方法。
	 * @param  data
	 */
	static appCallback(data) : any {
		let server = window.hyBirdServer;
		if (server.observers) {
			for (let [key, observer] of server.observers) {
				let result = observer.observe(data);
				if (result) {
					return result;
				}
			}
		}
	}

	/**
	 * 调用APP的方法，实际为AppNative.callApp
	 */
	callApp(data : Message) : any {
		let func = function (dataStr : string) : Message {
			//Tips:
			// 1)在Android端返回时只能用String。
			// 2)在Android返回时，可以用new Gson().toJson(message),将Message转换成String 返回。
			return window.AppNative.callApp(dataStr);
		}
		return func(JSON.stringify(data));
	}



	/**
	 * 添加app回调观察者
	 */
	addAppCallbackObserver(key : string, observer : IReceiveObserver) {
		let server = HyBirdServer.getInstance();
		if (server.observers) {
			server.observers.set(key, observer);
		}
	}

	/**
	 * 移除app回调观察者
	 */
	removeAppCallbackObserver(key : string) {
		let server = HyBirdServer.getInstance()
		if (server.observers && server.observers.has(key)) {
			server.observers.delete(key);
		}
	}

	/**
	 * 挂载到window上
	 */
	mountAtWindow() {
		//将其挂载到window上
		let mountObject = window;
		mountObject.hyBirdServer = this;
		mountObject.appCallback = HyBirdServer.appCallback;
	}


	// static Builder = class Builder {
	// 	constructor() {

	// 	}
	// 	build() : HyBirdServer {
	// 		let server = new HyBirdServer();
	// 		server.builder = this;
	// 		return server;
	// 	}
	// }
}
/**
 * 接收方法时
 */
type IReceiveObserver = {
	observe(data) : any;
}
/**
 * 交互的消息
 */
type Message = {
	action : number;
	data ?: {}
}
export {
	IReceiveObserver,
	Message
}